home *** CD-ROM | disk | FTP | other *** search
- /*
- BOBOLI main game executable
- By Mike Hommel
- CSC 404
- compile with DJGPP v2
- */
- #include "mgraph.h"
- #include "umk.h"
- #include "timer.h"
- #include "mkey.h"
- #include "mfont.h"
- #include "boboli.h"
- #include "guys.h"
- #include <stdio.h>
- #include "com.h"
-
- projectile prj[maxprjctls];
- displayrec disp[maxdisplay];
- genrec gen[maxgen];
- umkset stuff,guypix[numtypes],prjpix,objpix;
- scrntype scrn,scrn2;
- byte *backgd[2];
- byte curpage=0;
- byte anim=0;
- tileset tiles;
- paltype gamepal;
- colmat dark;
- maprec map;
- byte quit=0;
- short scrx,scry;
- creature guy[maxguys];
- playerrec player[numplayers];
- centerray guyctr[numtypes],prjctr,objctr;
- word randseed1=20; /* for my not-quite-random number generator */
- word randseed2=75;
- word randnum,randrange;
- rect validscreen={0,0,199,199};
- byte player_num; /* which of the players is on this computer */
- byte twoplayer=1;
- byte numcreatures=0;
-
- void titles(void)
- {
- paltype p;
- memset(p,0,768);
- setpal(p);
- loadPCX("pcx\\title.pcx",p,screen);
- fade_in(0,0,0,p);
- print(318-14*6,192,244,0,"PRESS A KEY...",screen);
- while((keystate(_Q)!=pressed)&&(keystate(_A)!=pressed)&&
- (keystate(_S)!=pressed)&&(keystate(_W)!=pressed));
- clear(0,screen);
- }
-
- byte intersect(rect s,rect d)
- {
- return ((s.x<=d.x2)&&(s.x2>=d.x)&&(s.y<=d.y2)&&
- (s.y2>=d.y)&&(s.x!=s.x2)&&(s.y!=s.y2)&&
- (d.x!=d.x2)&&(d.y!=d.y2));
- }
-
- word random(word range)
- {
- randrange=range;
- asm volatile ("pusha
- movw _randseed2,%ax
- movw _randseed1,%bx
- movw %ax,%si
- movw %bx,%di
- movb %ah,%dl
- movb %al,%ah
- movb %bh,%al
- movb %bl,%bh
- xorb %bl,%bl
- rcrb $1,%dl
- rcrw $1,%ax
- rcrw $1,%bx
- addw %di,%bx
- adcw %si,%ax
- addw $0x62e9,%bx
- adcw $0x3619,%ax
- movw %bx,_randseed2
- movw %ax,_randseed1
- xorw %dx,%dx
- movw _randrange,%cx
- divw %cx
- movw %dx,_randnum
- popa");
- return randnum;
- }
-
- void gamedelay(void)
- {
- asm volatile ("pushw %ax
- 1:
- movb _timetick,%al
- cmpb $0,%al
- jz 1b
- popw %ax
- ");
- timetick=0;
- waitretrace();
- }
-
- void loadctr(char *name,centerray c)
- {
- FILE *f;
- f=fopen(name,"rb");
- fread(c,1,sizeof(centerray),f);
- fclose(f);
- }
-
- void loadtiles(char *name,tileset t)
- {
- short i,j,k,x,y;
- paltype p;
- loadPCX(name,p,scrn);
- x=0; y=0;
- for(i=0;i<128;i++) {
- for(j=0;j<16;j++)
- for(k=0;k<16;k++)
- t[i][j+k*16]=scrn[x+j+(y+k)*320];
- x+=16;
- if(x>319) {
- x=0;
- y+=16;
- }
- }
- }
-
- void loadmap(void)
- {
- FILE *f;
- f=fopen("temp.map","rb");
- fread(map,sizeof(maprec),1,f);
- fread(gen,sizeof(genrec)*maxgen,1,f);
- fclose(f);
- }
-
- void get_input(byte wh)
- {
- if(guy[player[wh].who].hp>0) {
- player[wh].command=((keystate(Up)==pressed)||(keystate(Up)==held))*cmd_up+
- ((keystate(Down)==pressed)||(keystate(Down)==held))*cmd_dn+
- ((keystate(Left)==pressed)||(keystate(Left)==held))*cmd_lf+
- ((keystate(Right)==pressed)||(keystate(Right)==held))*cmd_rt+
- ((keystate(_Q)==pressed)||(keystate(_Q)==held))*cmd_at+
- (keystate(_A)==pressed)*cmd_drop+
- (keystate(_S)==pressed)*cmd_next+
- (keystate(_W)==pressed)*cmd_use;
- } else player[wh].command=0;
- }
-
- byte addcreature(byte kind,short x,short y,byte dir,byte control)
- {
- byte i=0;
- while((i<maxguys)&&(guy[i].kind!=nobody)) i++;
- if(i==maxguys) return 255;
- numcreatures++;
- guy[i].kind=kind;
- guy[i].hp=cd[kind].maxhp;
- guy[i].x=x;
- guy[i].y=y;
- guy[i].z=0;
- guy[i].dz=0;
- guy[i].dir=dir;
- guy[i].timer=0;
- guy[i].doing=do_stand;
- guy[i].frame=0;
- guy[i].control=control;
- guy[i].nearfoe=255;
- guy[i].friend=255;
- guy[i].state=0;
- return i;
- }
-
- byte addprjctl(byte kind,short x,short y,byte z,byte dir,byte launcher,byte lguy)
- {
- byte i=0;
- while((i<maxprjctls)&&(prj[i].kind!=pr_none)) i++;
- if(i==maxprjctls) return 255;
- prj[i].kind=kind;
- prj[i].x=x;
- prj[i].y=y;
- prj[i].z=z;
- prj[i].dir=dir%4;
- prj[i].launchguy=lguy;
- switch(kind) {
- case pr_spark: prj[i].timer=6;
- prj[i].dx=2-random(5);
- prj[i].dy=2-random(5);
- prj[i].dz=0;
- if(dir==1) prj[i].dz=1;
- break;
- case pr_golem: prj[i].timer=14;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- break;
- case pr_flower: prj[i].timer=26;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- break;
- case pr_shield: prj[i].timer=1;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- break;
- case pr_smoke: prj[i].timer=12;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=2;
- break;
- case pr_splash: prj[i].timer=35;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- break;
- case pr_tornado: prj[i].timer=50;
- prj[i].dx=2*(dir==0)-2*(dir==2);
- prj[i].dy=2*(dir==1)-2*(dir==3);
- prj[i].dz=0;
- break;
- case pr_hsprk: prj[i].timer=6;
- prj[i].dx=2-random(5);
- prj[i].dy=2-random(5);
- prj[i].dz=0;
- if(dir==1) prj[i].dz=1;
- break;
- case pr_arrow: prj[i].timer=0;
- prj[i].dx=7*(prj[i].dir==0)-7*(prj[i].dir==2);
- prj[i].dy=7*(prj[i].dir==1)-7*(prj[i].dir==3);
- prj[i].dz=0;
- if((dir>3)&&(dir<8)) {
- prj[i].dx+=3*(prj[i].dir==3)-3*(prj[i].dir==1);
- prj[i].dy+=3*(prj[i].dir==0)-3*(prj[i].dir==2);
- }
- if(dir>7) {
- prj[i].dx+=3*(prj[i].dir==1)-3*(prj[i].dir==3);
- prj[i].dy+=3*(prj[i].dir==2)-3*(prj[i].dir==0);
- }
- break;
- case pr_fball: prj[i].timer=5;
- prj[i].dx=5*(dir==0)-5*(dir==2);
- prj[i].dy=5*(dir==1)-5*(dir==3);
- prj[i].dz=0;
- break;
- case pr_burst: prj[i].timer=8;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- break;
- case pr_homing: prj[i].timer=35*5;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- break;
- case pr_skull: prj[i].timer=70;
- prj[i].dx=(dir==0)-(dir==2);
- prj[i].dy=(dir==1)-(dir==3);
- prj[i].dz=0;
- break;
- case pr_brightspot: prj[i].timer=10+(z>0)*4;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- prj[i].z=0;
- break;
- case pr_slime: prj[i].timer=0;
- prj[i].dx=4*(dir==0)-4*(dir==2);
- prj[i].dy=4*(dir==1)-4*(dir==3);
- prj[i].dz=3;
- break;
- case pr_splat: prj[i].timer=6;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- break;
- }
- prj[i].launcher=launcher;
- return i;
- }
-
-
- void init_player(byte wh)
- {
- byte i;
- strcpy(player[wh].name,"JAMUL");
- player[wh].color=19+wh*16;
- player[wh].command=0;
- player[wh].who=addcreature(boboli,32+wh*48+8,32,1,wh);
- player[wh].homex=(32+wh*48)/16;
- player[wh].homey=2;
- map[player[wh].homex+player[wh].homey*mapwidth].object=ob_genrtr;
- for(i=0;i<maxgen;i++) if(gen[i].kind==gn_none) {
- gen[i].kind=gn_boboli;
- gen[i].x=player[wh].homex;
- gen[i].y=player[wh].homey;
- gen[i].hp=1;
- gen[i].frame=1;
- i=maxgen;
- }
- guy[player[wh].who].state|=st_invis;
- guy[player[wh].who].state|=st_invinc;
- guy[player[wh].who].hp=0;
- guy[player[wh].who].friend=wh;
- player[wh].victimkind=255;
- player[wh].strength=1;
- player[wh].speed=1;
- player[wh].intellect=1;
- player[wh].armor=1;
- player[wh].skill=0;
- player[wh].magictimer=1;
- player[wh].selfhptimer=1;
- player[wh].magic=0;
- player[wh].selfhp=0;
- player[wh].realmagic=0;
- player[wh].realselfhp=0;
- player[wh].using=0;
- player[wh].messtimer=0;
- strcpy(player[wh].message,player[wh].name);
- player[wh].inv[0]=it_xbow;
- player[wh].invistimer=0;
- player[wh].invinctimer=0;
- for(i=1;i<6;i++)
- player[wh].inv[i]=0;
- }
-
- void init_boboli(void)
- {
- byte i;
- __djgpp_nearptr_enable();
- initmg();
- timer_init(FRAMERATE);
- kb_init();
- font_init("misc\\little.fnt");
- gmode(0x13);
- scrn=(scrntype)malloc(64000);
- scrn2=(scrntype)malloc(64000);
- backgd[0]=(byte *)malloc(backgdwidth*backgdheight);
- backgd[1]=(byte *)malloc(backgdwidth*backgdheight);
- mat_load("misc\\dark.mat",dark);
- umk_load("umks\\stuff.umk",stuff);
- umk_load("umks\\boboli.umk",guypix[0]);
- umk_load("umks\\bonehead.umk",guypix[1]);
- umk_load("umks\\glob.umk",guypix[2]);
- umk_load("umks\\golem.umk",guypix[3]);
- umk_load("umks\\orc.umk",guypix[4]);
- umk_load("umks\\mage.umk",guypix[5]);
- umk_load("umks\\prjctls.umk",prjpix);
- umk_load("umks\\objects.umk",objpix);
- loadctr("ctr\\boboli.ctr",guyctr[0]);
- loadctr("ctr\\bonehead.ctr",guyctr[1]);
- loadctr("ctr\\glob.ctr",guyctr[2]);
- loadctr("ctr\\golem.ctr",guyctr[3]);
- loadctr("ctr\\orc.ctr",guyctr[4]);
- loadctr("ctr\\mage.ctr",guyctr[5]);
- loadctr("ctr\\prjctls.ctr",prjctr);
- loadctr("ctr\\objects.ctr",objctr);
- loadtiles("pcx\\tiles.pcx",tiles);
- loadPCX("pcx\\main.pcx",gamepal,scrn2);
- titles();
- setpal(gamepal);
- for(i=0;i<maxguys;i++) guy[i].kind=nobody;
- for(i=0;i<maxprjctls;i++) prj[i].kind=pr_none;
- loadmap();
- init_player(0);
- if(twoplayer) init_player(1);
- addcreature(mage,60*16,54*16,1,255);
- }
-
- void exit_boboli(void)
- {
- kb_exit();
- timer_exit();
- gmode(0x3);
- umk_free(stuff);
- umk_free(prjpix);
- umk_free(objpix);
- umk_free(guypix[0]);
- umk_free(guypix[1]);
- umk_free(guypix[2]);
- free(scrn);
- free(scrn2);
- free(backgd[0]);
- free(backgd[1]);
- while(kbhit()) getch();
- __djgpp_nearptr_disable();
- }
-
- byte calc_shadows(byte x,byte y)
- {
- byte v;
- if(map[x+y*mapwidth].floor>63) return 0; /* no shadows on walls */
- if((map[x+y*mapwidth].floor==1)||(map[x+y*mapwidth].floor==2))
- return 0; /* no shadows on doors */
- if(x==0) {
- if(y==0) return 6;
- else if(map[x+(y-1)*mapwidth].floor>63) return 6;
- else return 2;
- }
- if(y==0) {
- if(map[x-1+y*mapwidth].floor>63) return 6;
- else return 4;
- }
- if(map[x-1+y*mapwidth].floor>63) {
- if(map[x+(y-1)*mapwidth].floor>63) return 6;
- if(map[x-1+(y-1)*mapwidth].floor>63) return 2;
- else return 1;
- }
- if(map[x+(y-1)*mapwidth].floor>63) {
- if(map[x-1+(y-1)*mapwidth].floor>63) return 4;
- else return 5;
- }
- if(map[x-1+(y-1)*mapwidth].floor>63) return 3;
- return 0;
- }
-
- long tilesrc,tiledst,tilecaddr;
- void tile_shadow(byte x,byte y,colmat c,umkrec u,byte *scr)
- {
- tilesrc=(long)u.img;
- tiledst=(long)(scr+x+y*backgdwidth);
- tilecaddr=(long)c;
- asm("pusha
- push %ds
- pop %es
- movl _tilesrc,%esi
- movl _tiledst,%edi
- movb $16,%dl
- movb $16,%dh
- xorl %eax,%eax
- movl _tilecaddr,%ebx
- tshloop1:
- movb %ds:(%esi),%al
- incl %esi
- cmpb $0,%al
- jnz tshnonzero
- movb %ds:(%esi),%al
- incl %esi
- addl %eax,%edi
- subb %al,%dl
- jnz tshloop1
- jmp tshlinedone
- tshnonzero:
- movb %es:(%edi),%al
- movb %ds:(%ebx,%eax),%al
- movb %al,%es:(%edi)
- incl %edi
- decb %dl
- jnz tshloop1
- tshlinedone:
- decb %dh
- jz tshdone
- addl $240,%edi
- movb $16,%dl
- jmp tshloop1
- tshdone:
- popa");
- }
-
- void draw_tile(byte x,byte y,tilerec t,byte *scr)
- {
- register byte i;
- for(i=0;i<16;i++) {
- memcpy(&(scr[x+y*backgdwidth]),&(tiles[t.floor][i*16]),16);
- y++;
- }
- y-=16;
- if(t.shadow>0)
- tile_shadow(x,y,dark,stuff[t.shadow-1],scr);
- }
-
- void draw_map(short x,short y)
- {
- byte i,j;
- byte sx,sy;
- sy=16-(y%16);
- for(j=(byte)(y/16);j<(byte)(y/16+14);j++) {
- sx=16-(x%16);
- for(i=(byte)(x/16);i<(byte)(x/16+14);i++) {
- draw_tile(sx,sy,map[i+j*mapwidth],backgd[0]);
- sx+=16;
- }
- sy+=16;
- }
- for(i=16;i<216;i++)
- memcpy(&(scrn[(i-16)*320]),&(backgd[0][16+i*backgdwidth]),200);
- curpage=0;
- }
-
- void scrollscr(short dx,short dy,scrntype src,scrntype dst)
- {
- long sofs,dofs,amt;
- amt=((256-abs(dx))>>2)+(255-abs(dy))*64+1;
- sofs=(long)src+(dy>0)*(dy*256);
- dofs=(long)dst+(dy<0)*(-dy*256);
- sofs+=(dx>0)*dx;
- dofs+=(dx<0)*(-dx);
- asm("pusha
- pushw %%ds
- popw %%es
- movl %0,%%esi
- movl %1,%%edi
- movl %2,%%ecx
- rep; movsl
- popa"::"m" (sofs),"m" (dofs),"m" (amt));
- }
-
- void update_inv(void)
- {
- short i,x=212,y=61;
- xfer(211,60,278+32+1,94+32+1,scrn2,scrn);
- for(i=0;i<6;i++) {
- if(player[player_num].inv[i]>it_none)
- umk_draw(x,y,stuff[7+player[player_num].inv[i]],scrn);
- if(player[player_num].using==i) umk_draw(x-1,y-1,stuff[8],scrn);
- x+=33;
- if(x>278) {
- x=212;
- y+=33;
- }
- }
- }
-
- void update_stats(void)
- {
- xfer(208,130,208+49,154+2,scrn2,scrn);
- box(208,130,207+player[player_num].strength,132,54,scrn);
- box(208,136,207+player[player_num].speed,138,54,scrn);
- box(208,142,207+player[player_num].intellect,144,54,scrn);
- box(208,148,207+player[player_num].armor,150,54,scrn);
- if(player[player_num].skill>0)
- box(208,154,207+(player[player_num].skill*50)/player[player_num].skillmax,156,54,scrn);
- }
-
- void data_display(void)
- {
- xfer(211,28,211+99,28+11,scrn2,scrn);
- xfer(211,45,211+99,45+11,scrn2,scrn);
- if(player[player_num].selfhp>player[player_num].realselfhp)
- player[player_num].selfhp--;
- if(player[player_num].selfhp<player[player_num].realselfhp)
- player[player_num].selfhp++;
- if(player[player_num].selfhp>0) {
- box(211,28,210+player[player_num].selfhp,28,42,scrn);
- box(211,29,210+player[player_num].selfhp,29,43,scrn);
- box(211,30,210+player[player_num].selfhp,37,39,scrn);
- box(211,38,210+player[player_num].selfhp,38,37,scrn);
- box(211,39,210+player[player_num].selfhp,39,36,scrn);
- }
- if(player[player_num].magic>player[player_num].realmagic)
- player[player_num].magic--;
- if(player[player_num].magic<player[player_num].realmagic)
- player[player_num].magic++;
- if(player[player_num].magic>0) {
- box(211,45,210+player[player_num].magic,45,24,scrn);
- box(211,46,210+player[player_num].magic,46,26,scrn);
- box(211,47,210+player[player_num].magic,54,23,scrn);
- box(211,55,210+player[player_num].magic,55,21,scrn);
- box(211,56,210+player[player_num].magic,56,20,scrn);
- }
- xfer(205,190,315,196,scrn2,scrn);
- if(player[player_num].messtimer==0) {
- print(206,191,15,8,player[player_num].message,scrn);
- } else {
- player[player_num].messtimer--;
- print(206,191,32+15-abs(15-player[player_num].messtimer/2),0,
- player[player_num].message,scrn);
- if(--player[player_num].messtimer==0) {
- strcpy(player[player_num].message,player[player_num].name);
- }
- }
- }
-
- void scrollmap(char dx,char dy)
- {
- byte i,j;
- byte sx,sy;
- short osx,osy;
- osx=scrx; osy=scry;
- scrx+=dx; scry+=dy;
- if(scrx<0) scrx=0;
- if(scrx>mapwidth*16-200-16) scrx=mapwidth*16-200-16;
- if(scry<0) scry=0;
- if(scry>mapheight*16-200-16) scry=mapheight*16-200-16;
- dx=scrx-osx; dy=scry-osy;
- scrollscr(dx,dy,backgd[curpage],backgd[1-curpage]);
- curpage=1-curpage;
- if(dx<0) {
- sx=16-(scrx%16);
- sy=16-(scry%16);
- for(j=(byte)(scry/16);j<(byte)(scry/16+14);j++) {
- draw_tile(sx,sy,map[(scrx/16)+j*mapwidth],backgd[curpage]);
- sy+=16;
- }
- }
- if(dx>0) {
- sx=16-(scrx%16)+16*13;
- sy=16-(scry%16);
- for(j=(byte)(scry/16);j<(byte)(scry/16+14);j++) {
- draw_tile(sx,sy,map[(scrx/16+13)+j*mapwidth],backgd[curpage]);
- sy+=16;
- }
- }
- if(dy<0) {
- sx=16-(scrx%16);
- sy=16-(scry%16);
- for(i=(byte)(scrx/16);i<(byte)(scrx/16+14);i++) {
- draw_tile(sx,sy,map[i+(scry/16)*mapwidth],backgd[curpage]);
- sx+=16;
- }
- }
- if(dy>0) {
- sx=16-(scrx%16);
- sy=16-(scry%16)+16*13;
- for(i=(byte)(scrx/16);i<(byte)(scrx/16+14);i++) {
- draw_tile(sx,sy,map[i+(scry/16+13)*mapwidth],backgd[curpage]);
- sx+=16;
- }
- }
- /* now animate the animated tiles. tile 3,4 is water */
- if(!(anim%8)) {
- sy=16-(scry%16);
- for(j=(byte)(scry/16);j<(byte)(scry/16+14);j++) {
- sx=16-(scrx%16);
- for(i=(byte)(scrx/16);i<(byte)(scrx/16+14);i++) {
- if((map[i+j*mapwidth].floor<5)&&(map[i+j*mapwidth].floor>2)) {
- map[i+j*mapwidth].floor=7-map[i+j*mapwidth].floor;
- draw_tile(sx,sy,map[i+j*mapwidth],backgd[curpage]);
- }
- sx+=16;
- }
- sy+=16;
- }
- }
- for(i=16;i<216;i++)
- memcpy(&(scrn[(i-16)*320]),&(backgd[curpage][16+i*backgdwidth]),200);
- }
-
- void draw_map_tile(byte x,byte y)
- {
- short sx,sy;
- sx=16-(scrx%16)+(x-(scrx/16))*16;
- sy=16-(scry%16)+(y-(scry/16))*16;
- if((sx>0)&&(sx<240)&&(sy>0)&&(sy<240))
- draw_tile(sx,sy,map[x+y*mapwidth],backgd[curpage]);
- }
-
- void change_tile(byte x,byte y,byte to)
- {
- map[x+y*mapwidth].floor=to;
- map[x+y*mapwidth].shadow=calc_shadows(x,y);
- draw_map_tile(x,y);
- if(x<mapwidth-1) {
- map[x+1+y*mapwidth].shadow=calc_shadows(x+1,y);
- draw_map_tile(x+1,y);
- }
- if(y<mapheight-1) {
- if(x<mapwidth-1) {
- map[x+1+(y+1)*mapwidth].shadow=calc_shadows(x+1,y+1);
- draw_map_tile(x+1,y+1);
- }
- map[x+(y+1)*mapwidth].shadow=calc_shadows(x,y+1);
- draw_map_tile(x,y+1);
- }
- }
-
- byte can_go(byte who,short x,short y)
- {
- rect r,r1,r2;
- byte i;
- r1.x=(x-4); r1.y=(y-6);
- r1.x2=(x+4); r1.y2=(y+2);
- r.x=r1.x/16; r.y=r1.y/16;
- r.x2=r1.x2/16; r.y2=r1.y2/16;
- if(guy[who].control<numplayers) {
- if(map[r.x+r.y*mapwidth].floor==64)
- change_tile(r.x,r.y,1);
- if(map[r.x+r.y*mapwidth].floor==65)
- change_tile(r.x,r.y,2);
- if(map[r.x2+r.y*mapwidth].floor==64)
- change_tile(r.x2,r.y,1);
- if(map[r.x2+r.y*mapwidth].floor==65)
- change_tile(r.x2,r.y,2);
- if(map[r.x+r.y2*mapwidth].floor==64)
- change_tile(r.x,r.y2,1);
- if(map[r.x+r.y2*mapwidth].floor==65)
- change_tile(r.x,r.y2,2);
- if(map[r.x2+r.y2*mapwidth].floor==64)
- change_tile(r.x2,r.y2,1);
- if(map[r.x2+r.y2*mapwidth].floor==65)
- change_tile(r.x2,r.y2,2);
- }
- if (!((map[r.x+r.y*mapwidth].floor<64)&&
- (map[r.x2+r.y*mapwidth].floor<64)&&
- (map[r.x+r.y2*mapwidth].floor<64)&&
- (map[r.x2+r.y2*mapwidth].floor<64))) return 0;
- switch(guy[who].kind) {
- case boboli: /*if(((map[r.x+r.y*mapwidth].object==ob_genrtr)&&
- ((r.x!=player[guy[who].control].homex)||
- (r.y!=player[guy[who].control].homey)))||
- ((map[r.x2+r.y*mapwidth].object==ob_genrtr)&&
- ((r.x2!=player[guy[who].control].homex)||
- (r.y!=player[guy[who].control].homey)))||
- ((map[r.x2+r.y2*mapwidth].object==ob_genrtr)&&
- ((r.x2!=player[guy[who].control].homex)||
- (r.y2!=player[guy[who].control].homey)))||
- ((map[r.x+r.y2*mapwidth].object==ob_genrtr)&&
- ((r.x!=player[guy[who].control].homex)||
- (r.y2!=player[guy[who].control].homey)))) return 0;*/
- case glob:
- case golem:
- case orc:
- case mage:
- case bonehead: if((guy[who].z==0)&&((map[r.x+r.y*mapwidth].floor==3)||
- (map[r.x2+r.y*mapwidth].floor==3)||
- (map[r.x+r.y2*mapwidth].floor==3)||
- (map[r.x2+r.y2*mapwidth].floor==3)||
- (map[r.x+r.y*mapwidth].floor==4)||
- (map[r.x2+r.y*mapwidth].floor==4)||
- (map[r.x+r.y2*mapwidth].floor==4)||
- (map[r.x2+r.y2*mapwidth].floor==4)))
- return 0;
- break;
- }
- for(i=0;i<maxguys;i++)
- if((i!=who)&&(guy[i].kind!=nobody)&&(guy[i].doing!=do_die)&&
- (abs(guy[i].x-guy[who].x)<32)&&(abs(guy[i].y-guy[who].y)<32)) {
- r2.x=guy[i].x-4; r2.y=guy[i].y-6;
- r2.x2=guy[i].x+4; r2.y2=guy[i].y+2;
- if(intersect(r1,r2)) return 0;
- }
- return 1;
- }
-
- void badguy_ai(byte i,word dist)
- {
- if((guy[i].doing!=do_stand)&&(guy[i].doing!=do_walk)) return;
- if(guy[i].z>0) return;
- if(guy[i].timer>0) {
- guy[i].timer--;
- if(guy[i].doing==do_walk) {
- guy[i].dx=((guy[i].dir==0)-(guy[i].dir==2))*cd[guy[i].kind].movspd;
- guy[i].dy=((guy[i].dir==1)-(guy[i].dir==3))*cd[guy[i].kind].movspd;
- if(!can_go(i,guy[i].x+guy[i].dx,guy[i].y)) guy[i].dx=0;
- if(!can_go(i,guy[i].x,guy[i].y+guy[i].dy)) guy[i].dy=0;
- }
- return;
- }
- if(guy[i].nearfoe!=255) {
- if(guy[guy[i].nearfoe].x<guy[i].x-2) guy[i].dx=-cd[guy[i].kind].movspd;
- if(guy[guy[i].nearfoe].x>guy[i].x+2) guy[i].dx=cd[guy[i].kind].movspd;
- if(guy[guy[i].nearfoe].y<guy[i].y-2) guy[i].dy=-cd[guy[i].kind].movspd;
- if(guy[guy[i].nearfoe].y>guy[i].y+2) guy[i].dy=cd[guy[i].kind].movspd;
- if(guy[i].doing==do_stand) {
- guy[i].doing=do_walk;
- guy[i].frame=0;
- } else if(guy[i].doing!=do_walk) {
- guy[i].dx=0; guy[i].dy=0;
- }
- if(!can_go(i,guy[i].x+guy[i].dx,guy[i].y)) guy[i].dx=0;
- if(!can_go(i,guy[i].x,guy[i].y+guy[i].dy)) guy[i].dy=0;
- if((guy[i].dx==0)&&(guy[i].dy==0)) {
- guy[i].doing=do_stand;
- guy[i].frame=0;
- }
- if(guy[i].doing==do_walk) {
- if(abs(guy[i].dx)>=abs(guy[i].dy)) guy[i].dir=2*(guy[i].dx<0);
- else guy[i].dir=1+2*(guy[i].dy<0);
- }
- if(dist<cd[guy[i].kind].range) {
- guy[i].doing=do_melee;
- guy[i].frame=0;
- guy[i].dx=0; guy[i].dy=0;
- if(guy[i].kind==mage) guy[i].timer=10;
- }
- if((!random(25))&&(guy[i].kind!=golem)) {
- guy[i].doing=do_walk;
- guy[i].frame=0;
- guy[i].dir=random(4);
- guy[i].timer=4+random(16);
- }
- if((!random(90))&&(guy[i].kind!=golem)) {
- guy[i].doing=do_stand;
- guy[i].frame=0;
- guy[i].timer=random(30);
- }
- if((abs(guy[guy[i].nearfoe].x-guy[i].x)<600)&&
- (abs(guy[guy[i].nearfoe].y-guy[i].y)<600)) {
- if((guy[i].kind==glob)&&(guy[i].doing==do_stand)&&(!random(40))) {
- guy[i].doing=do_arrow;
- guy[i].frame=0;
- guy[i].timer=0;
- }
- if((guy[i].kind==mage)&&(guy[i].doing==do_walk)&&(!random(20))) {
- guy[i].doing=do_arrow;
- guy[i].frame=0;
- guy[i].timer=0;
- if(!random(30)) guy[i].doing=do_spell;
- }
- }
- } else {
- if(guy[i].doing==do_walk) guy[i].doing=do_stand;
- guy[i].frame=0;
- guy[i].dx=0;
- guy[i].dy=0;
- }
- }
-
- void use_item(byte who)
- {
- switch(player[guy[who].control].inv[player[guy[who].control].using]) {
- case it_none: break;
- case it_3xbow:
- case it_fxbow:
- case it_xbow: guy[who].doing=do_arrow;
- guy[who].frame=0;
- break;
- case it_souledge2: guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_souledge2;
- break;
- case it_fball: if(player[guy[who].control].realmagic>=10) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_fball;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- case it_summon: if(player[guy[who].control].realmagic>=40) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_summon;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- case it_greenthumb: if(player[guy[who].control].realmagic>=20) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_greenthumb;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- case it_healing: if(player[guy[who].control].realmagic>=40) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_healing;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- case it_invis: if(player[guy[who].control].realmagic>=40) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_invis;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- case it_shieldspl: if(player[guy[who].control].realmagic>=40) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_shieldspl;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- case it_tornado: if(player[guy[who].control].realmagic>=10) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_tornado;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- case it_inferno: if(player[guy[who].control].realmagic>=20) {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=it_inferno;
- } else {
- guy[who].doing=do_spell;
- guy[who].frame=0;
- player[guy[who].control].spell=0; /* spell fizzles */
- }
- break;
- }
- }
-
- void set_item_message(byte pnum,byte itm)
- {
- if(itm!=it_none) {
- player[pnum].messtimer=60;
- switch(itm) {
- case it_xbow: strcpy(player[pnum].message,"CROSSBOW");
- break;
- case it_3xbow: strcpy(player[pnum].message,"TRIPLE CROSSBOW");
- break;
- case it_fxbow: strcpy(player[pnum].message,"FLAMING CROSSBOW");
- break;
- case it_elfswd: strcpy(player[pnum].message,"ELVEN SWORD");
- break;
- case it_gntswd: strcpy(player[pnum].message,"GIANT SWORD");
- break;
- case it_souledge2:
- case it_souledge: strcpy(player[pnum].message,"SOUL EDGE");
- break;
- case it_mirshield: strcpy(player[pnum].message,"MIRROR SHIELD");
- break;
- case it_fball: strcpy(player[pnum].message,"FIREBALL SPELL");
- break;
- case it_inferno: strcpy(player[pnum].message,"INFERNO SPELL");
- break;
- case it_tornado: strcpy(player[pnum].message,"TORNADO SPELL");
- break;
- case it_greenthumb: strcpy(player[pnum].message,"NATURE SPELL");
- break;
- case it_shieldspl: strcpy(player[pnum].message,"SHIELD SPELL");
- break;
- case it_healing: strcpy(player[pnum].message,"HEALING SPELL");
- break;
- case it_summon: strcpy(player[pnum].message,"SUMMON SPELL");
- break;
- case it_invis: strcpy(player[pnum].message,"CLOAKING SPELL");
- break;
- }
- }
- }
-
- byte get_item(byte who,byte itm)
- {
- byte i;
- if(player[who].inv[player[who].using]==it_none) {
- player[who].inv[player[who].using]=itm;
- set_item_message(who,itm);
- if(itm==it_souledge) player[who].souledgecharge=0;
- if(itm==it_souledge2) player[who].souledgecharge=souledgefull;
- return 1;
- } else {
- for(i=0;i<6;i++)
- if(player[who].inv[i]==it_none) {
- player[who].inv[i]=itm;
- set_item_message(who,itm);
- if(itm==it_souledge) player[who].souledgecharge=0;
- if(itm==it_souledge2) player[who].souledgecharge=souledgefull;
- return 1;
- }
- }
- return 0;
- }
-
- void set_other_message(byte pnum,char *msg)
- {
- player[pnum].messtimer=60;
- strcpy(player[pnum].message,msg);
- }
-
- void player_control(byte i)
- {
- byte j,k;
- j=player[guy[i].control].command;
- if(j&cmd_next) {
- player[guy[i].control].using++;
- if(player[guy[i].control].using==6) player[guy[i].control].using=0;
- set_item_message(guy[i].control,player[guy[i].control].inv[player[guy[i].control].using]);
- if(guy[i].control==player_num) update_inv();
- }
- if(j&cmd_drop) {
- k=map[(guy[i].x/16)+(guy[i].y/16)*mapwidth].object;
- if(k==ob_none) {
- switch(player[guy[i].control].inv[player[guy[i].control].using]) {
- case it_none: break;
- default: map[(guy[i].x/16)+(guy[i].y/16)*mapwidth].object=
- player[guy[i].control].inv[player[guy[i].control].using];
- player[guy[i].control].inv[player[guy[i].control].using]=it_none;
- set_other_message(guy[i].control,"DROPPED!");
- break;
- }
- } else {
- switch(k) {
- case ob_genrtr: break;
- default: if(get_item(guy[i].control,k))
- map[(guy[i].x/16)+(guy[i].y/16)*mapwidth].object=ob_none;
- break;
- }
- }
- update_inv();
- }
- if((guy[i].z==0)&&((guy[i].doing==do_stand)||(guy[i].doing==do_walk))) {
- if((j&cmd_up)||(j&cmd_dn)||(j&cmd_lf)||(j&cmd_rt)) {
- if(guy[i].doing==do_stand) {
- guy[i].doing=do_walk;
- guy[i].frame=0;
- }
- if(j&cmd_up) {
- guy[i].dir=3;
- guy[i].dy=-(player[guy[i].control].speed/24+2);
- }
- if(j&cmd_dn) {
- guy[i].dir=1;
- guy[i].dy=(player[guy[i].control].speed/24+2);
- }
- if(j&cmd_lf) {
- guy[i].dir=2;
- guy[i].dx=-(player[guy[i].control].speed/24+2);
- }
- if(j&cmd_rt) {
- guy[i].dir=0;
- guy[i].dx=(player[guy[i].control].speed/24+2);
- }
- } else {
- guy[i].doing=do_stand;
- guy[i].frame=0;
- }
- if(j&cmd_at) {
- guy[i].doing=do_melee;
- guy[i].frame=0;
- }
- if(j&cmd_use)
- use_item(i);
- }
- if(!can_go(i,guy[i].x+guy[i].dx,guy[i].y)) guy[i].dx=0;
- if(!can_go(i,guy[i].x,guy[i].y+guy[i].dy)) guy[i].dy=0;
- }
-
- void gain_level(byte who)
- {
- byte w;
- if((player[who].strength==50)&&(player[who].speed==50)&&
- (player[who].intellect==50)&&(player[who].armor==50)) {
- player[who].skill=0;
- return;
- }
- for(w=0;w<4;w++) { /* add 4 points randomly to the attributes */
- switch(random(4)) {
- case 0: if(player[who].strength<50) player[who].strength++;
- else w--;
- break;
- case 1: if(player[who].speed<50) player[who].speed++;
- else w--;
- break;
- case 2: if(player[who].intellect<50) player[who].intellect++;
- else w--;
- break;
- case 3: if(player[who].armor<50) player[who].armor++;
- else w--;
- break;
- }
- }
- player[who].skill-=player[who].skillmax;
- if(player[who].skillmax<100) player[who].skillmax+=5;
- set_other_message(who,"LEVEL UP!");
- }
-
- word calc_dmg(byte attacker)
- {
- word d;
- if(guy[attacker].control<numplayers) {
- d=((4+player[guy[attacker].control].strength)+
- random(player[guy[attacker].control].strength+1))/4;
- /* Giant Sword does double damage */
- if(player[guy[attacker].control].inv[player[guy[attacker].control].using]==
- it_gntswd) d*=2;
- } else switch(guy[attacker].kind) {
- case boboli: d=5+random(20);
- break;
- case bonehead: d=2+random(5);
- break;
- case orc: d=5+random(6);
- break;
- case mage: d=20+random(20);
- break;
- case glob: d=1+random(4);
- break;
- case golem: d=20+random(10);
- break;
- }
- return d;
- }
-
- word damage(byte attacker,byte victim)
- {
- word d;
- byte ohp;
- ohp=(guy[victim].hp*100)/cd[guy[victim].kind].maxhp;
- d=calc_dmg(attacker);
- if(guy[victim].control<numplayers) {
- d=((128-player[guy[victim].control].armor)*d)/128;
- }
- guy[victim].hp-=d;
- if(guy[victim].kind==mage) guy[victim].state&=(0xFF-st_invis);
- if(d>10) {
- guy[victim].doing=do_bigouch;
- if(guy[victim].z==0) guy[victim].dz=4;
- guy[victim].frame=0;
- }
- if(guy[victim].hp<=0) {
- guy[victim].hp=0;
- guy[victim].doing=do_bigouch;
- guy[victim].frame=0;
- if(guy[attacker].control<numplayers) {
- player[guy[attacker].control].skill+=cd[guy[victim].kind].xpvalue;
- while(player[guy[attacker].control].skill>player[guy[attacker].control].skillmax)
- gain_level(guy[attacker].control);
- if(guy[attacker].control==player_num) update_stats();
- }
- }
- if(guy[attacker].control<numplayers) {
- player[guy[attacker].control].victimkind=guy[victim].kind;
- player[guy[attacker].control].victimcurhp=ohp;
- player[guy[attacker].control].victimhp=(guy[victim].hp*100)/cd[guy[victim].kind].maxhp;
- player[guy[attacker].control].hptimer=70;
- }
- if(guy[victim].control<numplayers) {
- player[guy[victim].control].realselfhp=(guy[victim].hp*100)/cd[guy[victim].kind].maxhp;
- }
- return d;
- }
-
- byte calc_p_dmg(byte attacker)
- {
- byte d;
- switch(prj[attacker].kind) {
- case pr_arrow: d=2+random(7);
- break;
- case pr_fball: d=5+random(6);
- break;
- case pr_homing: d=7+random(5);
- break;
- case pr_burst: d=5+random(5);
- break;
- case pr_flower: d=1;
- break;
- case pr_skull: d=255;
- break;
- case pr_tornado_hit:
- case pr_tornado_done:
- case pr_tornado: d=0;
- break;
- case pr_inferno: if(prj[attacker].timer>9) d=1; else d=0;
- break;
- case pr_slime: d=5+random(6);
- break;
- }
- return d;
- }
-
- void prj_damage(byte attacker,byte victim)
- {
- byte d;
- byte ohp;
- d=calc_p_dmg(attacker);
- ohp=(guy[victim].hp*100)/cd[guy[victim].kind].maxhp;
- if(guy[victim].control<numplayers) {
- d=((128-player[guy[victim].control].armor)*d)/128;
- }
- guy[victim].hp-=d;
- if(guy[victim].kind==mage) guy[victim].state&=(0xFF-st_invis);
- if(guy[victim].hp<=0) {
- guy[victim].hp=0;
- guy[victim].doing=do_bigouch;
- guy[victim].frame=0;
- if(prj[attacker].launcher<numplayers) {
- player[prj[attacker].launcher].skill+=cd[guy[victim].kind].xpvalue;
- while(player[prj[attacker].launcher].skill>player[prj[attacker].launcher].skillmax)
- gain_level(prj[attacker].launcher);
- if(prj[attacker].launcher==player_num) update_stats();
- }
- }
- if(prj[attacker].kind==pr_tornado) {
- prj[attacker].kind=pr_tornado_hit;
- prj[attacker].timer=70;
- guy[victim].x=prj[attacker].x;
- guy[victim].y=prj[attacker].y;
- guy[victim].dz=2;
- prj[attacker].dx>>=1;
- prj[attacker].dy>>=1;
- } else if(prj[attacker].kind==pr_tornado_hit) {
- guy[victim].dir=(++guy[victim].dir)%4;
- guy[victim].x=prj[attacker].x;
- guy[victim].y=prj[attacker].y;
- if(guy[victim].dz<4) guy[victim].dz+=1+random(2);
- if(guy[victim].z>32) guy[victim].dz=0;
- } else if(guy[victim].z==0) guy[victim].dz=4;
- if(prj[attacker].launcher<numplayers) {
- player[prj[attacker].launcher].victimkind=guy[victim].kind;
- player[prj[attacker].launcher].victimcurhp=ohp;
- player[prj[attacker].launcher].victimhp=(guy[victim].hp*100)/cd[guy[victim].kind].maxhp;
- player[prj[attacker].launcher].hptimer=35;
- }
- if(guy[victim].control<numplayers)
- player[guy[victim].control].realselfhp=(guy[victim].hp*100)/cd[guy[victim].kind].maxhp;
- }
-
- void hit_generator(byte dmg,byte who,byte i,byte x,byte y,byte info)
- {
- byte j;
- byte ohp;
- if(gen[i].kind==gn_boboli) return;
- ohp=gen[i].hp;
- gen[i].hp-=dmg;
- switch(info) {
- case 0: addprjctl(pr_hsprk,x*16+8-8+random(16),y*16+8-8+random(16),random(16),0,255,0);
- break;
- case 1: addprjctl(pr_smoke,x*16+8-8+random(16),y*16+8-8+random(16),2,0,255,0);
- if(player[guy[who].control].souledgecharge<souledgefull) {
- player[guy[who].control].souledgecharge+=dmg;
- if(player[guy[who].control].souledgecharge>=souledgefull) {
- player[guy[who].control].inv[player[guy[who].control].using]=it_souledge2;
- if(guy[who].control==player_num) update_inv();
- }
- }
- }
- if(gen[i].hp>ohp) {
- gen[i].hp=0;
- gen[i].kind=gn_none;
- map[x+y*mapwidth].object=ob_none;
- for(j=0;j<15;j++)
- addprjctl(pr_hsprk,x*16+8-16+random(32),y*16+8-16+random(32),random(16),0,255,0);
- if(who<numplayers) {
- player[who].skill+=50;
- while(player[who].skill>player[who].skillmax)
- gain_level(who);
- if(who==player_num) update_stats();
- }
- }
- if(who<numplayers) {
- player[who].victimkind=254;
- player[who].victimcurhp=(ohp*100)/150;
- player[who].victimhp=(gen[i].hp*100)/150;
- if((player[who].victimhp==0)&&(gen[i].hp>0)) {
- player[who].victimhp=1;
- }
- player[who].hptimer=70;
- }
- }
-
- void strike_em(byte who)
- {
- rect r1,r2;
- byte i=guy[who].dir*cd[guy[who].kind].numframes;
- word j;
- switch(guy[who].dir) {
- case 0: if(map[(guy[who].x/16+1)+(guy[who].y/16)*mapwidth].floor>=64) return;
- break;
- case 1: if(map[(guy[who].x/16)+(guy[who].y/16+1)*mapwidth].floor>=64) return;
- break;
- case 2: if(map[(guy[who].x/16-1)+(guy[who].y/16)*mapwidth].floor>=64) return;
- break;
- case 3: if(map[(guy[who].x/16)+(guy[who].y/16-1)*mapwidth].floor>=64) return;
- break;
- }
- r1.x=guy[who].x-
- guyctr[guy[who].kind][i+cd[guy[who].kind].move[do_melee][guy[who].frame]].x;
- r1.y=guy[who].y-
- guyctr[guy[who].kind][i+cd[guy[who].kind].move[do_melee][guy[who].frame]].y;
- r1.x2=r1.x+
- guypix[guy[who].kind][i+cd[guy[who].kind].move[do_melee][guy[who].frame]].width;
- r1.y2=r1.y+
- guypix[guy[who].kind][i+cd[guy[who].kind].move[do_melee][guy[who].frame]].height;
- switch(guy[who].dir) {
- case 0: r1.x+=(r1.x2-r1.x)/4;
- r1.y+=(r1.y2-r1.y)/4;
- r1.y2-=(r1.y2-r1.y)/4;
- break;
- case 1: r1.y+=(r1.y2-r1.y)/4;
- r1.x+=(r1.x2-r1.x)/4;
- r1.x2-=(r1.x2-r1.x)/4;
- break;
- case 2: r1.x2-=(r1.x2-r1.x)/4;
- r1.y+=(r1.y2-r1.y)/4;
- r1.y2-=(r1.y2-r1.y)/4;
- break;
- case 3: r1.y2-=(r1.y2-r1.y)/4;
- r1.x+=(r1.x2-r1.x)/4;
- r1.x2-=(r1.x2-r1.x)/4;
- break;
- }
- if(guy[who].control<numplayers) {
- if((player[guy[who].control].inv[player[guy[who].control].using]==it_souledge)||
- (player[guy[who].control].inv[player[guy[who].control].using]==it_souledge2))
- j=1; else j=0;
- for(i=0;i<maxgen;i++) if(gen[i].kind!=gn_none) {
- r2.x=gen[i].x*16; r2.y=gen[i].y*16;
- r2.x2=gen[i].x*16+15; r2.y2=gen[i].y*16+15;
- if(intersect(r1,r2))
- hit_generator(calc_dmg(who),guy[who].control,i,gen[i].x,gen[i].y,j);
- }
- }
- for(i=0;i<maxguys;i++) if((guy[i].kind!=nobody)&&
- ((guy[who].friend==255)||(guy[who].friend!=guy[i].control))&&
- ((guy[i].control!=guy[who].control)||(guy[who].kind==golem))&&
- (guy[i].hp>0)&&(i!=who)&&
- (!(guy[i].state&st_invinc))&&(!((guy[i].doing==do_bigouch)&&
- (guy[i].frame>=cd[guy[i].kind].active_frame[do_bigouch])))) {
- r2.x=guy[i].x-4; r2.y=guy[i].y-6;
- r2.x2=guy[i].x+4; r2.y2=guy[i].y+2;
- if(intersect(r1,r2)) {
- guy[i].doing=do_ouch;
- guy[i].frame=0;
- if(guy[who].dir==0) guy[i].dir=2;
- if(guy[who].dir==1) guy[i].dir=3;
- if(guy[who].dir==2) guy[i].dir=0;
- if(guy[who].dir==3) guy[i].dir=1;
- j=damage(who,i);
- if(guy[who].control<numplayers) {
- if((player[guy[who].control].inv[player[guy[who].control].using]==it_souledge)||
- (player[guy[who].control].inv[player[guy[who].control].using]==it_souledge2)) {
- addprjctl(pr_smoke,r2.x+random(8),r2.y+random(8),2,0,255,0);
- if(player[guy[who].control].souledgecharge<souledgefull) {
- player[guy[who].control].souledgecharge+=j;
- if(player[guy[who].control].souledgecharge>=souledgefull) {
- player[guy[who].control].inv[player[guy[who].control].using]=it_souledge2;
- if(guy[who].control==player_num) update_inv();
- }
- }
- } else
- if((player[guy[who].control].inv[player[guy[who].control].using]==it_elfswd)||
- (player[guy[who].control].inv[player[guy[who].control].using]==it_gntswd)) {
- addprjctl(pr_spark,r2.x+random(8),r2.y+random(8),random(32),0,255,0);
- addprjctl(pr_spark,r2.x+random(8),r2.y+random(8),random(32),0,255,0);
- addprjctl(pr_hsprk,r2.x+random(8),r2.y+random(8),random(32),0,255,0);
- } else addprjctl(pr_hsprk,r2.x+random(8),r2.y+random(8),random(32),0,255,0);
- } else
- addprjctl(pr_hsprk,r2.x+random(8),r2.y+random(8),random(32),0,255,0);
- }
- }
- }
-
- void fire_shot(byte who)
- {
- short ax,ay;
- switch(guy[who].kind) {
- case boboli: ax=guy[who].x; ay=guy[who].y;
- ax+=25*(guy[who].dir==0)-25*(guy[who].dir==2)+
- 2*(guy[who].dir==3)-2*(guy[who].dir==1);
- ay+=20*(guy[who].dir==1)-20*(guy[who].dir==3)+
- 2*(guy[who].dir==0)-2*(guy[who].dir==2);
- if(map[(ax/16)+(ay/16)*mapwidth].floor>=64) break;
- if((guy[who].dir==0)&&(map[((ax-16)/16)+(ay/16)*mapwidth].floor>=64)) break;
- if((guy[who].dir==1)&&(map[(ax/16)+((ay-16)/16)*mapwidth].floor>=64)) break;
- if((guy[who].dir==2)&&(map[((ax+16)/16)+(ay/16)*mapwidth].floor>=64)) break;
- if((guy[who].dir==3)&&(map[(ax/16)+((ay+16)/16)*mapwidth].floor>=64)) break;
- if(guy[who].control<numplayers) {
- switch(player[guy[who].control].inv[player[guy[who].control].using]) {
- case it_xbow: addprjctl(pr_arrow,ax,ay,24,guy[who].dir,guy[who].control,0);
- break;
- case it_fxbow: addprjctl(pr_fball,ax,ay,24,guy[who].dir,guy[who].control,0);
- break;
- case it_3xbow: addprjctl(pr_arrow,ax,ay,24,guy[who].dir+4,guy[who].control,0);
- addprjctl(pr_arrow,ax,ay,24,guy[who].dir,guy[who].control,0);
- addprjctl(pr_arrow,ax,ay,24,guy[who].dir+8,guy[who].control,0);
- break;
- default: break;
- }
- } else addprjctl(pr_arrow,ax,ay,24,guy[who].dir,guy[who].control,0);
- break;
- case glob: ax=guy[who].x; ay=guy[who].y;
- ax+=20*(guy[who].dir==0)-20*(guy[who].dir==2);
- ay+=17*(guy[who].dir==1)-17*(guy[who].dir==3);
- if(map[(ax/16)+(ay/16)*mapwidth].floor>=64) break;
- addprjctl(pr_slime,ax,ay,20,guy[who].dir,guy[who].control,0);
- break;
- case mage: ax=guy[who].x; ay=guy[who].y;
- ax+=15*(guy[who].dir==0)-15*(guy[who].dir==2);
- ay+=12*(guy[who].dir==1)-12*(guy[who].dir==3);
- if(map[(ax/16)+(ay/16)*mapwidth].floor>=64) break;
- addprjctl(pr_homing,ax,ay,20,guy[who].dir,guy[who].control,who);
- break;
- }
- }
-
- void plant_flowers(byte minx,byte miny,byte maxx,byte maxy,byte x,byte y,byte num,byte dir,byte con)
- {
- byte i;
- for(i=0;i<maxprjctls;i++)
- if((prj[i].kind==pr_flower)&&(prj[i].x==x*16+8)&&
- (prj[i].y==y*16+8)) return;
- if((x>minx)&&(x<maxx)&&(y>miny)&(y<maxy)&&(num>0)&&
- (map[x+y*mapwidth].floor<64)&&
- (map[x+y*mapwidth].floor!=3)&&
- (map[x+y*mapwidth].floor!=4)) {
- if(map[x+y*mapwidth].object==ob_none)
- addprjctl(pr_flower,x*16+8,y*16+8,0,dir,con,0);
- plant_flowers(minx,miny,maxx,maxy,x-1,y,num-1,dir,con);
- plant_flowers(minx,miny,maxx,maxy,x+1,y,num-1,dir,con);
- plant_flowers(minx,miny,maxx,maxy,x,y-1,num-1,dir,con);
- plant_flowers(minx,miny,maxx,maxy,x,y+1,num-1,dir,con);
- }
- }
-
- void cast_spell(byte who,byte spl)
- {
- short ax,ay;
- for(ax=0;ax<5;ax++)
- addprjctl(pr_spark,guy[who].x-10+random(20),guy[who].y-10+random(20),
- random(32),0,255,0);
- switch(spl) {
- case 0: break; /* fizzled spell */
- case it_greenthumb: if(guy[who].control<numplayers)
- player[guy[who].control].realmagic-=20;
- ax=guy[who].x/16+(guy[who].dir==0)-(guy[who].dir==2);
- ay=guy[who].y/16+(guy[who].dir==1)-(guy[who].dir==3);
- plant_flowers(1+((guy[who].x/16-1)*(guy[who].dir==0)),
- 1+((guy[who].y/16-1)*(guy[who].dir==1)),
- (mapwidth-2)*(guy[who].dir!=2)+
- ((guy[who].x/16))*(guy[who].dir==2),
- (mapheight-2)*(guy[who].dir!=3)+
- ((guy[who].y/16))*(guy[who].dir==3),
- ax,ay,4,guy[who].dir,guy[who].control);
- break;
- case it_healing: if(guy[who].control<numplayers) {
- player[guy[who].control].realmagic-=40;
- player[guy[who].control].realselfhp=(guy[who].hp*100)/cd[boboli].maxhp;
- }
- guy[who].hp+=50+random(51);
- if(guy[who].hp>cd[0].maxhp) guy[who].hp=cd[boboli].maxhp;
- break;
- case it_invis: if(guy[who].control<numplayers) {
- player[guy[who].control].realmagic-=40;
- player[guy[who].control].invistimer=350;
- }
- guy[who].state|=st_invis;
- break;
- case it_shieldspl: if(guy[who].control<numplayers) {
- player[guy[who].control].realmagic-=40;
- player[guy[who].control].invinctimer=350;
- }
- guy[who].state|=st_invinc;
- addprjctl(pr_shield,guy[who].x,guy[who].y,0,0,guy[who].control,0);
- break;
- case it_summon: if(guy[who].control<numplayers)
- player[guy[who].control].realmagic-=40;
- ax=guy[who].x; ay=guy[who].y;
- ax+=32*(guy[who].dir==0)-32*(guy[who].dir==2);
- ay+=32*(guy[who].dir==1)-32*(guy[who].dir==3);
- addprjctl(pr_golem,ax,ay,0,0,guy[who].control,0);
- break;
- case it_souledge2: ax=guy[who].x; ay=guy[who].y;
- if(map[(ax/16)+(ay/16)*mapwidth].floor>=64) break;
- addprjctl(pr_skull,ax,ay,10,guy[who].dir,guy[who].control,0);
- if(guy[who].control<numplayers) {
- player[guy[who].control].souledgecharge=0;
- for(ax=0;ax<6;ax++)
- if(player[guy[who].control].inv[ax]==it_souledge2)
- player[guy[who].control].inv[ax]=it_souledge;
- if(guy[who].control==player_num) update_inv();
- }
- break;
- case it_fball: ax=guy[who].x; ay=guy[who].y;
- ax+=10*(guy[who].dir==0)-10*(guy[who].dir==2);
- ay+=10*(guy[who].dir==1)-10*(guy[who].dir==3);
- if(map[(ax/16)+(ay/16)*mapwidth].floor>=64) break;
- addprjctl(pr_fball,ax,ay,24,guy[who].dir,guy[who].control,0);
- if(guy[who].control<numplayers)
- player[guy[who].control].realmagic-=10;
- break;
- case it_tornado: ax=guy[who].x; ay=guy[who].y;
- if(map[(ax/16)+(ay/16)*mapwidth].floor>=64) break;
- addprjctl(pr_tornado,ax,ay,0,guy[who].dir,guy[who].control,0);
- if(guy[who].control<numplayers)
- player[guy[who].control].realmagic-=10;
- break;
- case it_inferno: ax=guy[who].x; ay=guy[who].y;
- /* near ones */
- addprjctl(pr_brightspot,ax,ay-10 ,0,3,guy[who].control,0);
- addprjctl(pr_brightspot,ax+10,ay-5,0,0,guy[who].control,0);
- addprjctl(pr_brightspot,ax+10,ay+5,0,0,guy[who].control,0);
- addprjctl(pr_brightspot,ax,ay+10 ,0,1,guy[who].control,0);
- addprjctl(pr_brightspot,ax-10,ay+5,0,2,guy[who].control,0);
- addprjctl(pr_brightspot,ax-10,ay-5,0,2,guy[who].control,0);
- /* far ones */
- addprjctl(pr_brightspot,ax,ay-20 ,1,3,guy[who].control,0);
- addprjctl(pr_brightspot,ax+20,ay-10,1,0,guy[who].control,0);
- addprjctl(pr_brightspot,ax+25,ay ,1,0,guy[who].control,0);
- addprjctl(pr_brightspot,ax+20,ay+10,1,0,guy[who].control,0);
- addprjctl(pr_brightspot,ax,ay+20 ,1,1,guy[who].control,0);
- addprjctl(pr_brightspot,ax-20,ay+10,1,2,guy[who].control,0);
- addprjctl(pr_brightspot,ax-25,ay ,1,2,guy[who].control,0);
- addprjctl(pr_brightspot,ax-20,ay-10,1,2,guy[who].control,0);
- if(guy[who].control<numplayers)
- player[guy[who].control].realmagic-=20;
- break;
- }
- }
-
- /* finds an unoccupied square a maximum of depth squares from starting pos
- that is accessible from the starting pos (not through a wall) */
- void find_home(byte who,short *x,short *y,byte depth)
- {
- byte i,cnt;
- short tx,ty;
- if(!depth) return;
- tx=(*x); ty=(*y);
- for(cnt=0;cnt<10;cnt++) {
- i=random(4);
- switch(i) {
- case 0: (*x)--;
- break;
- case 1: (*x)++;
- break;
- case 2: (*y)--;
- break;
- case 3: (*y)++;
- break;
- }
- if((map[(*x)+(*y)*mapwidth].floor<64)&&(map[(*x)+(*y)*mapwidth].floor!=3)&&
- (map[(*x)+(*y)*mapwidth].floor!=4)) {
- for(i=0;i<maxguys;i++)
- if((i!=who)&&(guy[i].kind!=nobody)&&(guy[i].x/16==*x)&&(guy[i].y/16==*y)) {
- (*x)=tx; (*y)=ty;
- i=maxguys;
- }
- } else {
- (*x)=tx; (*y)=ty;
- }
- }
- if((tx!=(*x))||(ty!=(*y)))
- find_home(who,x,y,depth-1);
- }
-
- void moveguys(void)
- {
- byte i,j,rept;
- short x,y;
- word dist;
- rept=0;
- for(i=0;i<maxguys;i++) if(guy[i].kind!=nobody) {
- if(guy[i].dz>-8) guy[i].dz--;
- guy[i].z+=guy[i].dz;
- if(guy[i].z>200) {
- guy[i].z=0;
- guy[i].dz=0;
- }
- if((guy[i].nearfoe!=255)&&(!(guy[guy[i].nearfoe].state&st_invis)))
- dist=abs(guy[guy[i].nearfoe].x-guy[i].x)+
- abs(guy[guy[i].nearfoe].y-guy[i].y);
- else dist=65535;
- for(j=0;j<maxguys;j++) {
- if((j!=i)&&(guy[j].kind!=nobody)&&(guy[j].control!=guy[i].control)&&
- (!(guy[j].state&st_invis))&&(guy[j].friend!=guy[i].control)&&
- ((abs(guy[j].x-guy[i].x)+abs(guy[j].y-guy[i].y))<dist)) {
- guy[i].nearfoe=j;
- dist=abs(guy[j].x-guy[i].x)+
- abs(guy[j].y-guy[i].y);
- }
- }
- if(guy[i].friend<numplayers) {
- guy[i].nearfoe=guy[player[guy[i].friend].who].nearfoe;
- dist=abs(guy[guy[i].nearfoe].x-guy[i].x)+
- abs(guy[guy[i].nearfoe].y-guy[i].y);
- }
- guy[i].dx=0;
- guy[i].dy=0;
- if(guy[i].control<numplayers)
- player_control(i);
- else
- badguy_ai(i,dist);
- if(guy[i].doing==do_bigouch) {
- if(guy[i].frame<cd[guy[i].kind].active_frame[do_bigouch]) {
- guy[i].dx=2*(guy[i].dir==2)-2*(guy[i].dir==0);
- guy[i].dy=2*(guy[i].dir==3)-2*(guy[i].dir==1);
- if(!can_go(i,guy[i].x+guy[i].dx,guy[i].y+guy[i].dy)) {
- guy[i].dx=0;
- guy[i].dy=0;
- }
- } else if(guy[i].hp==0) {
- guy[i].doing=do_die;
- guy[i].frame=0;
- }
- }
- if(guy[i].doing==do_die) {
- switch(guy[i].kind) {
- case golem: addprjctl(pr_smoke,guy[i].x-10+random(20),
- guy[i].y-10+random(20),random(5),0,255,0);
- break;
- case mage: addprjctl(pr_smoke,guy[i].x-10+random(20),
- guy[i].y-10+random(20),random(5),0,255,0);
- addprjctl(pr_spark,guy[i].x-10+random(20),
- guy[i].y-10+random(20),random(5),0,255,0);
-
- break;
- default: break;
- }
- }
- guy[i].x+=guy[i].dx;
- guy[i].y+=guy[i].dy;
- guy[i].frame++;
- if((guy[i].doing==do_melee)&&
- (guy[i].frame==cd[guy[i].kind].active_frame[do_melee])) {
- if(guy[i].kind!=mage) strike_em(i);
- else {
- x=guy[i].x+15*(guy[i].dir==0)-15*(guy[i].dir==2);
- y=guy[i].y+10*(guy[i].dir==1)-10*(guy[i].dir==3);
- addprjctl(pr_burst,x,y,0,guy[i].dir,guy[i].control,0);
- }
- }
- if((guy[i].doing==do_arrow)&&
- (guy[i].frame==cd[guy[i].kind].active_frame[do_arrow]))
- fire_shot(i);
- if((guy[i].doing==do_spell)&&
- (guy[i].frame==cd[guy[i].kind].active_frame[do_spell])) {
- if(guy[i].control<numplayers)
- cast_spell(i,player[guy[i].control].spell);
- else if(guy[i].kind==mage) {
- j=random(20);
- if(j<6) cast_spell(i,it_inferno);
- else if(j<10) cast_spell(i,it_invis);
- else if(j<15) cast_spell(i,it_tornado);
- else if(j<18) cast_spell(i,it_summon);
- else cast_spell(i,it_souledge2);
- }
- }
- if(cd[guy[i].kind].move[guy[i].doing][guy[i].frame]==255) {
- if(guy[i].doing==do_die) {
- if(guy[i].control>=numplayers) {
- guy[i].kind=255;
- numcreatures--;
- } else {
- guy[i].hp=0;
- guy[i].state|=st_invis;
- guy[i].state|=st_invinc;
- guy[i].x=player[guy[i].control].homex*16+8;
- guy[i].y=player[guy[i].control].homey*16;
- guy[i].dir=1;
- for(j=0;j<maxgen;j++) {
- if((gen[j].x==player[guy[i].control].homex)&&
- (gen[j].y==player[guy[i].control].homey)&&
- (gen[j].kind==gn_boboli)) {
- gen[j].frame=1;
- j=maxgen;
- }
- }
- }
- }
- if((guy[i].doing==do_bigouch)&&(guy[i].kind==mage)) {
- guy[i].doing=do_get; /* "get" for the mage is not get, but actually */
- guy[i].frame=0; /* unteleport */
- guy[i].x/=16;
- guy[i].y/=16;
- find_home(i,&(guy[i].x),&(guy[i].y),3);
- guy[i].x=guy[i].x*16+8;
- guy[i].y=guy[i].y*16+8;
- } else {
- guy[i].doing=do_stand;
- guy[i].frame=0;
- }
- }
- if((guy[i].z==0)&&((map[(guy[i].x/16)+(guy[i].y/16)*mapwidth].floor==3)||
- (map[(guy[i].x/16)+(guy[i].y/16)*mapwidth].floor==4))) {
- addprjctl(pr_splash,guy[i].x,guy[i].y,0,0,255,0);
- if(guy[i].control>=numplayers) {
- guy[i].kind=nobody;
- numcreatures--;
- } else {
- guy[i].state|=st_invis;
- guy[i].state|=st_invinc;
- guy[i].x=player[guy[i].control].homex*16+8;
- guy[i].y=player[guy[i].control].homey*16;
- guy[i].dir=1;
- guy[i].hp=0;
- for(j=0;j<maxgen;j++) {
- if((gen[j].x==player[guy[i].control].homex)&&
- (gen[j].y==player[guy[i].control].homey)&&
- (gen[j].kind==gn_boboli)) {
- gen[j].frame=1;
- j=maxgen;
- }
- }
- }
- }
- /* check for doublespeed issues */
- if((guy[i].control<numplayers)&&(rept==0)) {
- if(guy[i].doing==do_melee) {
- if(player[guy[i].control].inv[player[guy[i].control].using]==it_elfswd)
- rept=2;
- }
- }
- if(rept>1) {
- i--;
- rept--;
- }
- }
- }
-
- byte figure_prjpic(projectile p)
- {
- switch(p.kind) {
- case pr_spark: return 2-((p.timer-1)/2);
- break;
- case pr_golem: return 92-((p.timer-1)/2);
- break;
- case pr_flower: return 85-((p.timer-1)/2);
- break;
- case pr_shield: return 70+random(3);
- break;
- case pr_smoke: return 45-((p.timer-1)/2);
- break;
- case pr_hsprk: return (6-p.timer)+19;
- break;
- case pr_arrow: return p.dir+3;
- break;
- case pr_fball: return p.dir+11;
- break;
- case pr_burst: return 95-(abs(4-p.timer)/2);
- break;
- case pr_homing: return 96+(p.timer%2);
- break;
- case pr_inferno: return 18-abs(10-p.timer)/4;
- break;
- case pr_brightspot: return 15;
- break;
- case pr_slime: return 7;
- break;
- case pr_splat: return 10-((p.timer-1)/2);
- break;
- case pr_tornado:
- case pr_tornado_hit: return 25+p.timer%9;
- break;
- case pr_tornado_done: return 36-((p.timer-1)/2);
- break;
- case pr_splash: return 39-(p.timer>30)-(p.timer>25)-(p.timer<5)-(p.timer<3);
- break;
- case pr_skull: return 46+(p.dir*6)+(p.timer>2)*abs(3-(p.timer/2)%7)+
- (p.timer<3)*(6-p.timer);
- break;
- }
- }
-
- byte prj_can_go(byte who,short x,short y)
- {
- rect r,r1,r2;
- byte i,j;
- if((prj[who].kind==pr_spark)||(prj[who].kind==pr_splat)||(prj[who].kind==pr_splash)||
- (prj[who].kind==pr_smoke)||(prj[who].kind==pr_hsprk)||(prj[who].kind==pr_shield)||
- (prj[who].kind==pr_brightspot)||(prj[who].kind==pr_tornado_done)||
- (prj[who].kind==pr_golem))
- return 1;
- r1.x=(x-4); r1.y=(y-6);
- r1.x2=(x+4); r1.y2=(y+2);
- r.x=r1.x/16; r.y=r1.y/16;
- r.x2=r1.x2/16; r.y2=r1.y2/16;
- if(prj[who].kind==pr_skull) {
- for(i=r.x-2;i<r.x2+2;i++)
- for(j=r.y-2;j<r.y2+2;j++) {
- if((i>0)&&(j>0)&&(i<mapwidth-1)&&(j<mapheight-1)&&
- ((map[i+j*mapwidth].floor>=64)||
- (map[i+j*mapwidth].floor==1)||
- (map[i+j*mapwidth].floor==2)))
- change_tile(i,j,15);
- }
- r1.x-=16; r1.x2+=16;
- r1.y-=16; r1.y2+=16;
- }
- if (!((map[r.x+r.y*mapwidth].floor<64)&&
- (map[r.x2+r.y*mapwidth].floor<64)&&
- (map[r.x+r.y2*mapwidth].floor<64)&&
- (map[r.x2+r.y2*mapwidth].floor<64)))
- return 0;
- if(prj[who].launcher<numplayers)
- for(i=0;i<maxgen;i++) if(gen[i].kind!=gn_none) {
- r2.x=gen[i].x*16; r2.y=gen[i].y*16;
- r2.x2=gen[i].x*16+15; r2.y2=gen[i].y*16+15;
- if(intersect(r1,r2)) {
- if(prj[who].kind==pr_tornado) {
- prj[who].kind=pr_tornado_done;
- prj[who].timer=6;
- }
- hit_generator(calc_p_dmg(who),prj[who].launcher,i,gen[i].x,gen[i].y,2);
- if(prj[who].kind!=pr_skull) return 0;
- }
- }
- for(i=0;i<maxguys;i++)
- if((guy[i].control!=prj[who].launcher)&&(guy[i].kind!=nobody)&&
- (guy[i].hp>0)&&(!(guy[i].state&st_invinc))&&
- ((guy[i].doing!=do_bigouch)||
- (guy[i].frame<cd[guy[i].kind].active_frame[do_bigouch]))) {
- r2.x=guy[i].x-4; r2.y=guy[i].y-6;
- r2.x2=guy[i].x+4; r2.y2=guy[i].y+2;
- if(intersect(r1,r2)) {
- guy[i].doing=do_bigouch;
- guy[i].frame=0;
- if((prj[who].kind!=pr_tornado_hit)&&(prj[who].kind!=pr_tornado)) {
- if(prj[who].dir==0) guy[i].dir=2;
- if(prj[who].dir==1) guy[i].dir=3;
- if(prj[who].dir==2) guy[i].dir=0;
- if(prj[who].dir==3) guy[i].dir=1;
- prj_damage(who,i);
- return 0;
- } else {
- prj_damage(who,i);
- return 1;
- }
- }
- }
- return 1;
- }
-
- void moveprjs(void)
- {
- byte i,j;
- word dist;
- for(i=0;i<maxprjctls;i++) if(prj[i].kind!=pr_none) {
- prj[i].x+=prj[i].dx;
- prj[i].y+=prj[i].dy;
- prj[i].z+=prj[i].dz;
- if(prj[i].kind==pr_slime) {
- prj[i].dz--;
- if(prj[i].z>200) {
- prj[i].kind=pr_splat;
- prj[i].dx=0;
- prj[i].dy=0;
- prj[i].dz=0;
- prj[i].z=0;
- prj[i].timer=6;
- }
- }
- if((!prj_can_go(i,prj[i].x,prj[i].y))&&(prj[i].kind!=pr_inferno)&&
- (prj[i].kind!=pr_skull)&&(prj[i].kind!=pr_burst)) {
- if(prj[i].kind==pr_slime) prj[i].kind=pr_splat;
- else if((prj[i].kind==pr_tornado)||(prj[i].kind==pr_tornado_hit))
- prj[i].kind=pr_tornado_done;
- else prj[i].kind=pr_hsprk;
- prj[i].dx>>=1;
- prj[i].dy>>=1;
- prj[i].dz=0;
- prj[i].timer=6;
- }
- if(prj[i].kind==pr_skull)
- addprjctl(pr_smoke,prj[i].x-16+random(32),prj[i].y-16+random(32),2,0,255,0);
- if(prj[i].timer>0) {
- prj[i].timer--;
- if((prj[i].kind==pr_homing)&&(!(prj[i].timer%5))&&(guy[prj[i].launchguy].nearfoe!=255)) {
- if(prj[i].x<guy[guy[prj[i].launchguy].nearfoe].x) prj[i].dx++;
- else prj[i].dx--;
- if(prj[i].y<guy[guy[prj[i].launchguy].nearfoe].y) prj[i].dy++;
- else prj[i].dy--;
- if(prj[i].dx>8) prj[i].dx=8;
- if(prj[i].dx<-8) prj[i].dx=-8;
- if(prj[i].dy>8) prj[i].dy=8;
- if(prj[i].dy<-8) prj[i].dy=-8;
- if(abs(prj[i].dy)>abs(prj[i].dx))
- prj[i].dir=1+(prj[i].dy<0);
- else prj[i].dir=(prj[i].dx<0);
- }
- if(prj[i].timer==0) {
- switch(prj[i].kind) {
- case pr_spark:
- case pr_skull:
- case pr_smoke:
- case pr_splash:
- case pr_burst:
- case pr_homing:
- case pr_hsprk:
- case pr_inferno:
- case pr_tornado_done:
- case pr_splat: prj[i].kind=pr_none;
- break;
- case pr_golem: prj[i].kind=pr_none;
- j=addcreature(golem,prj[i].x,prj[i].y,1,255);
- if(j!=255)
- guy[j].friend=prj[i].launcher;
- break;
- case pr_flower: prj[i].kind=pr_none;
- map[(prj[i].x/16)+(prj[i].y/16)*mapwidth].object=ob_flower;
- break;
- case pr_shield: if(player[prj[i].launcher].invinctimer>0) {
- prj[i].timer=1;
- prj[i].x=guy[player[prj[i].launcher].who].x;
- prj[i].y=guy[player[prj[i].launcher].who].y;
- }
- else prj[i].kind=pr_none;
- break;
- case pr_tornado_hit:
- case pr_tornado: prj[i].timer=6;
- prj[i].kind=pr_tornado_done;
- break;
- case pr_fball: prj[i].timer=5;
- addprjctl(pr_spark,prj[i].x,prj[i].y,prj[i].z,1,255,0);
- break;
- case pr_brightspot: prj[i].timer=19;
- prj[i].kind=pr_inferno;
- break;
- }
- }
- }
- }
- }
-
- void movegens(void)
- {
- byte i,w;
- for(i=0;i<maxgen;i++) {
- if(gen[i].kind!=gn_none) {
- if((gen[i].frame==0)&&(gen[i].kind!=gn_boboli)) {
- if(!(--gen[i].timer)) {
- gen[i].frame=1;
- gen[i].timer=100+random(400);
- }
- } else if(gen[i].frame!=0) {
- gen[i].frame++;
- switch(gen[i].kind) {
- case gn_bonehead: if(gen[i].frame==20) {
- w=addcreature(bonehead,gen[i].x*16+8,gen[i].y*16+8,
- 1,255);
- if(!can_go(w,gen[i].x*16+8,gen[i].y*16+8)) {
- guy[w].kind=nobody;
- }
- gen[i].frame=0;
- }
- break;
- case gn_glob: if(gen[i].frame==16) {
- w=addcreature(glob,gen[i].x*16+8,gen[i].y*16+8,
- 1,255);
- if(!can_go(w,gen[i].x*16+8,gen[i].y*16+8)) {
- guy[w].kind=nobody;
- }
- gen[i].frame=0;
- }
- break;
- case gn_boboli: if(gen[i].frame==19) {
- for(w=0;w<numplayers;w++) {
- if((player[w].homex==gen[i].x)&&
- (player[w].homey==gen[i].y)) {
- guy[player[w].who].state^=st_invis;
- guy[player[w].who].state^=st_invinc;
- guy[player[w].who].doing=do_stand;
- guy[player[w].who].frame=0;
- guy[player[w].who].hp=cd[0].maxhp;
- player[w].realselfhp=100;
- }
- }
- gen[i].frame=0;
- }
- break;
- }
- }
- }
- }
- }
-
- void stick_in_a_mean_orc(void)
- {
- byte x,y;
- short dist;
- x=random(mapwidth);
- y=random(mapheight);
- if(map[x+y*mapwidth].floor==0) {
- dist=abs(x-(guy[player[0].who].x/16))+
- abs(y-(guy[player[0].who].y/16));
- if(dist<20) return;
- if(twoplayer) {
- dist=abs(x-(guy[player[1].who].x/16))+
- abs(y-(guy[player[1].who].y/16));
- if(dist<20) return;
- }
- addcreature(orc,x*16+8,y*16+8,0,255);
- }
- }
-
- void update_loop(void)
- {
- byte i;
- get_input(player_num);
- if(twoplayer) {
- player[1-player_num].command=recv_packet();
- send_packet(player[player_num].command);
- while(!data_rcvd) player[1-player_num].command=recv_packet();
- data_rcvd=0;
- }
- if((numcreatures<20)&&(!random(100)))
- stick_in_a_mean_orc();
- for(i=0;i<numplayers;i++) {
- if(--player[i].magictimer==0) {
- if(player[i].realmagic<player[i].intellect*2) player[i].realmagic++;
- player[i].magictimer=(40-player[i].intellect/2)+1;
- }
- if(--player[i].selfhptimer==0) {
- if((guy[player[i].who].hp<cd[player[i].who].maxhp)&&
- (guy[player[i].who].hp>0)) {
- guy[player[i].who].hp++;
- player[i].realselfhp=(guy[player[i].who].hp*100)/cd[player[i].who].maxhp;
- }
- player[i].selfhptimer=(210-player[i].strength*2-player[i].armor*2);
- }
- if(player[i].invistimer>0) {
- if(!--player[i].invistimer) {
- guy[player[i].who].state&=(255-st_invis);
- }
- }
- if(player[i].invinctimer>0) {
- if(!--player[i].invinctimer) {
- guy[player[i].who].state&=(255-st_invinc);
- }
- }
- }
- moveguys();
- moveprjs();
- movegens();
- }
-
- byte figure_genpic(byte x,byte y)
- {
- byte i,z;
- for(i=0;i<maxgen;i++) {
- if((gen[i].x==x)&&(gen[i].y==y)) {
- switch(gen[i].kind) {
- case gn_boboli: z=gen[i].frame/2;
- break;
- case gn_bonehead: z=10+gen[i].frame;
- break;
- case gn_glob: z=30+gen[i].frame;
- break;
- }
- return z;
- }
- }
- }
-
- void showguys(void)
- {
- void insertdisp(umkrec u,byte mode,byte value,short x,short y,short cmpy)
- {
- byte i,spot=255;
- switch(mode) {
- case md_floor: for(i=0;i<maxdisplay;i++)
- if((disp[i].mode!=md_floor)||
- (disp[i].cmpy>cmpy)) {
- spot=i;
- i=maxdisplay;
- }
- break;
- case md_shadow: for(i=0;i<maxdisplay;i++)
- if((disp[i].mode==md_normal)||
- (disp[i].mode==md_none)||
- (disp[i].mode==md_boboli)) {
- spot=i;
- i=maxdisplay;
- }
- break;
- case md_normal:
- case md_boboli: for(i=0;i<maxdisplay;i++)
- if(((disp[i].mode==md_normal)&&(disp[i].cmpy>cmpy))||
- (disp[i].mode==md_none)||
- ((disp[i].mode==md_boboli)&&(disp[i].cmpy>cmpy))) {
- spot=i;
- i=maxdisplay;
- }
- break;
- }
- if(spot==255) return;
- for(i=maxdisplay-1;i>spot;i--)
- memcpy(&(disp[i]),&(disp[i-1]),sizeof(displayrec));
- disp[spot].u=u;
- disp[spot].mode=mode;
- disp[spot].value=value;
- disp[spot].x=x;
- disp[spot].y=y;
- disp[spot].cmpy=cmpy;
- }
- short i,j,x,y,z;
- for(i=0;i<maxdisplay;i++) disp[i].mode=md_none;
- for(i=0;i<maxguys;i++) if((guy[i].kind!=nobody)&&(guy[i].x>scrx-50)&&
- (guy[i].y>scry-50)&&(guy[i].x<scrx+250)&&
- (guy[i].y<scry+250)) {
- j=cd[guy[i].kind].move[guy[i].doing][guy[i].frame]+
- guy[i].dir*cd[guy[i].kind].numframes;
- if((guy[i].z>0)||((guy[i].state&st_invis)&&(guy[i].control==player_num)&&
- (guy[i].hp>0)))
- insertdisp(guypix[guy[i].kind][j],md_shadow,0,
- guy[i].x-scrx-guyctr[guy[i].kind][j].x,
- guy[i].y-scry-guyctr[guy[i].kind][j].y,
- guy[i].y);
- if(!(guy[i].state&st_invis)) {
- if(guy[i].control<numplayers)
- insertdisp(guypix[guy[i].kind][j],md_boboli,player[guy[i].control].color,
- guy[i].x-scrx-guyctr[guy[i].kind][j].x,
- guy[i].y-scry-guyctr[guy[i].kind][j].y-guy[i].z/2,
- guy[i].y);
- else
- insertdisp(guypix[guy[i].kind][j],md_normal,0,
- guy[i].x-scrx-guyctr[guy[i].kind][j].x,
- guy[i].y-scry-guyctr[guy[i].kind][j].y-guy[i].z/2,
- guy[i].y);
- }
- }
- for(i=0;i<maxprjctls;i++) if(prj[i].kind!=pr_none) {
- j=figure_prjpic(prj[i]);
- if((prj[i].kind!=pr_spark)&&(prj[i].kind!=pr_brightspot)&&
- (prj[i].kind!=pr_splash)&&(prj[i].kind!=pr_inferno)&&
- (prj[i].kind!=pr_smoke)&&(prj[i].kind!=pr_hsprk)&&
- (prj[i].kind!=pr_golem)&&(prj[i].kind!=pr_shield)&&
- (prj[i].kind!=pr_burst))
- insertdisp(prjpix[j],md_shadow,0,prj[i].x-scrx-prjctr[j].x,
- prj[i].y-scry-prjctr[j].y,prj[i].y);
- insertdisp(prjpix[j],md_normal,0,prj[i].x-scrx-prjctr[j].x,
- prj[i].y-scry-prjctr[j].y-(prj[i].z/2),prj[i].y);
- }
- x=-8-(scrx%16);
- for(i=scrx/16-1;i<scrx/16+14;i++) {
- y=-8-(scry%16);
- for(j=scry/16-1;j<scry/16+14;j++) {
- if((i>-1)&&(i<mapwidth)&&(j>-1)&&(j<mapheight)) switch(map[i+j*mapwidth].object) {
- case ob_none: break;
- case ob_genrtr: z=figure_genpic(i,j);
- insertdisp(objpix[z],md_floor,0,x-objctr[z].x,
- y-objctr[z].y,y);
- break;
- default: z=44+map[i+j*mapwidth].object;
- insertdisp(objpix[z],md_floor,0,x-objctr[z].x,
- y-objctr[z].y,y);
- break;
- }
- y+=16;
- }
- x+=16;
- }
- for(i=0;i<maxdisplay;i++)
- switch(disp[i].mode) {
- case md_floor:
- case md_normal: umk_limit(validscreen,disp[i].x,disp[i].y,disp[i].u,scrn);
- break;
- case md_boboli: umk_255limit(validscreen,disp[i].x,disp[i].y,disp[i].value,disp[i].u,scrn);
- break;
- case md_shadow: umk_shadowlimit(validscreen,disp[i].x,disp[i].y,dark,disp[i].u,scrn);
- break;
- }
- }
-
- void display_loop(void)
- {
- short dx=0,dy=0;
- anim++;
- if(scrx<guy[player[player_num].who].x-120) {
- dx+=2;
- if(scrx<guy[player[player_num].who].x-150) dx+=2;
- if(scrx<guy[player[player_num].who].x-200) dx+=4;
- }
- if(scry<guy[player[player_num].who].y-120) {
- dy+=2;
- if(scry<guy[player[player_num].who].y-150) dy+=2;
- if(scry<guy[player[player_num].who].y-200) dy+=4;
- }
- if(scrx>guy[player[player_num].who].x-80) {
- dx-=2;
- if(scrx>guy[player[player_num].who].x-50) dx-=2;
- if(scrx>guy[player[player_num].who].x) dx-=4;
- }
- if(scry>guy[player[player_num].who].y-80) {
- dy-=2;
- if(scry>guy[player[player_num].who].y-50) dy-=2;
- if(scry>guy[player[player_num].who].y) dy-=4;
- }
- scrollmap(dx,dy);
- showguys();
- data_display();
- if(player[player_num].victimkind<255) {
- if(!--player[player_num].hptimer) player[player_num].victimkind=255;
- else {
- umk_draw(10,177,stuff[7],scrn);
- if(player[player_num].victimcurhp>0) {
- box(12,179,12+player[player_num].victimcurhp,179,22,scrn);
- box(12,180,12+player[player_num].victimcurhp,180,26,scrn);
- box(12,181,12+player[player_num].victimcurhp,179+10,24,scrn);
- box(12,179+11,12+player[player_num].victimcurhp,179+11,22,scrn);
- }
- if(player[player_num].victimcurhp>player[player_num].victimhp)
- player[player_num].victimcurhp--;
- else if(player[player_num].victimcurhp<player[player_num].victimhp)
- player[player_num].victimcurhp++;
- if(player[player_num].victimkind<200)
- print(13,182,15*((player[player_num].victimhp>0)||(curpage>0)),8,cd[player[player_num].victimkind].name,scrn);
- else
- print(13,182,15*((player[player_num].victimhp>0)||(curpage>0)),8,"GENERATOR",scrn);
- }
- }
- }
-
- void the_game(void)
- {
- scrx=0; scry=0;
- scrcpy(scrn2,scrn);
- update_inv();
- update_stats();
- draw_map(scrx,scry);
- while(!quit) {
- update_loop();
- if(player[1-player_num].command==Player_pressed_ESC) {
- quit=1;
- break;
- }
- display_loop();
- gamedelay();
- near_scrcpy(scrn,screen);
- if(keystate(Esc)==pressed) {
- if(twoplayer) {
- qdelay(2000); /* in case the other computer is not quite ready */
- send_packet(Player_pressed_ESC);
- }
- quit=1;
- }
- }
- }
-
- void main(short argc,char *argv[])
- {
- if(argc!=2) {
- printf("BOBOLI 0|1|2 (0=1-player game, 1 or 2=COM port)\n");
- return;
- } else {
- player_num=argv[1][0]-'0';
- if(player_num==0) {
- twoplayer=0;
- } else if(player_num>2) {
- printf("BOBOLI 0|1|2 (0=1-player game, 1 or 2=COM port)\n");
- return;
- } else {
- player_num--;
- init_rs232(player_num);
- }
- }
- init_boboli();
- the_game();
- exit_boboli();
- }
-